
    /**  
    * @Title: HTTPGatewayService.java
    * @Package com.efast.cafe.commponent.es.http.controller
    * @Description: TODO(用一句话描述该文件做什么)
    * @author Administrator
    * @date 2018年10月19日
    * @version V1.0  
    */
    
package com.efast.cafe.commponent.es.http;

import java.util.UUID;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.MDC;
import org.slf4j.event.Level;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.alibaba.fastjson.JSONObject;
import com.cafeauto.http.Message;
import com.efast.cafe.commponent.es.common.entity.CommonEsConfig;
import com.efast.cafe.commponent.es.common.enums.ServiceTypeEnum;
import com.efast.cafe.commponent.es.common.service.CommonEsConfigService;
import com.efast.cafe.commponent.es.http.constant.HttpConstant;
import com.efast.cafe.commponent.log.ext.CafeLogger;
import com.efast.cafe.commponent.log.ext.CafeLoggerFactory;
import com.efast.cafe.framework.exception.ServiceException;
import com.efast.cafe.util.ConfigUtil;
import com.efast.cafe.util.HMAC;
import com.efast.cafe.util.IpAddressUtil;
import com.efast.cafe.util.ProxyDelegate;
import com.efast.cafe.util.StringUtil;

/**
    * @ClassName: HTTPGatewayService
    * @Description: 对外http统一接口
    * @author Administrator
    * @date 2018年10月19日
    *
    */
@ConditionalOnProperty(
        name="http.enable",
        havingValue="true"
)
@Controller
@RequestMapping("/openHTTP/doHTTPService")
public class HTTPGatewayService {
	
	@Autowired
	private CommonEsConfigService commonEsConfigService;

	
	private CafeLogger logger = CafeLoggerFactory.getLogger(getClass());
	
	private static String systemName = ConfigUtil.getSystemIndentifier();
	
	@RequestMapping(value="/{bizCode}",method= RequestMethod.POST)
	public @ResponseBody Message doService(@PathVariable String bizCode,@ModelAttribute Message message,
			HttpServletRequest request){
		MDC.put("companyCode","");
		MDC.put("userName", message.getMessageFrom());
		MDC.put("clientIP",IpAddressUtil.getIpAdrress(request)); 
		String uuid = UUID.randomUUID().toString().replaceAll("-", "");
		boolean enableLog = false;
		try{
			
			String messageFrom = message.getMessageFrom();
			String hmac = message.getHmac();
			String version = StringUtil.isNullOrBlank(message.getVersion())?"1": message.getVersion();
			if(StringUtil.isNullOrBlank(bizCode)){
				throw new ServiceException(HttpConstant.RetCode.PARAM_NULL,"'bizCode' Can't be empty.");
			}
			
			if(StringUtil.isNullOrBlank(messageFrom)){
				throw new ServiceException(HttpConstant.RetCode.PARAM_NULL,"'messageFrom' Can't be empty.");
			}
			
			
			logger.info("Received a http message from "+message.getMessageFrom());
			
			message.setMessageId(StringUtil.isNullOrBlank(message.getMessageId())?uuid:message.getMessageId());
			
			CommonEsConfig config =	commonEsConfigService.getConfig(ServiceTypeEnum.HTTP.name(), bizCode, message.getMessageFrom());
			
			if(null==config){
				throw new ServiceException(HttpConstant.RetCode.CONFIG_NULL,"The interface config is undefined.");
			}
			enableLog = (config.getLogs()!=null && config.getLogs().intValue()==1);
			
			if(enableLog){
				logger.cacheLog(Level.INFO, JSONObject.toJSONString(message), "HTTP-Received-"+message.getBizCode()+","+message.getMessageId());
			}
			
			
			//获取来源系统的私钥
			String securet = config.getSec();
			
			//如果对来源系统配置了密钥，则系统需要hmac校验
			boolean isHmac = StringUtil.isNullOrBlank(securet)?false:true;
			
			if(isHmac && StringUtil.isNullOrBlank(hmac)){
				throw new ServiceException(HttpConstant.RetCode.PARAM_NULL,"'hmac' Can't be empty.");
			}
			
			if(isHmac && StringUtil.isNullOrBlank(securet)){
				throw new ServiceException(HttpConstant.RetCode.CONFIG_NULL,"Could not find the interface config in "+systemName+" Service GateWay.");
			}
			
			if(isHmac){
				String bizContent = message.getBizContent();
				//计算HMAC值
				String hmacValid = HMAC.encryptHMAC(bizContent, securet);
				if(isHmac && !hmacValid.equals(hmac)){
					throw new ServiceException(HttpConstant.RetCode.VALUE_ERROR,"hmac value check failed.");
				}
				byte[] byteContent = null;
				//base64解码
				try {
					byteContent = HMAC.decryptBase64(bizContent.trim());
				} catch (Exception e1) {
					throw new ServiceException(HttpConstant.RetCode.VALUE_ERROR,"BASE64 decode error.");
				}
				String encodeContent = new String(byteContent);//json str
				message.setBizContent(encodeContent);
			}
			
			String className = HttpConstant.getHttpServiceClass(bizCode+version);
			if(StringUtil.isNullOrBlank(className)){
				throw new ServiceException(HttpConstant.RetCode.CONFIG_NULL,"Could not find the processing class.");
			}
			Message returnMessage =	(Message)ProxyDelegate.invoke(className, "handleMessage", new Object[]{message});
			if(enableLog){
				logger.cacheLog(Level.INFO, JSONObject.toJSONString(returnMessage),"HTTP-Response-"+message.getBizCode()+","+message.getMessageId());
			}
			return returnMessage;
		}catch(Exception e){
			message.setSuccess(false);
			if(e instanceof ServiceException){
				ServiceException ex = (ServiceException)e;
				message.setRetCode(ex.getCode());
				message.setRetCodeDesc(StringUtil.isNotBlank(e.getMessage())?e.getMessage():e.getLocalizedMessage());
			}else{
				message.setRetCode("SystemError");
				message.setRetCodeDesc(e.getMessage());
			}
			if(enableLog){
				logger.cacheLog(Level.INFO, JSONObject.toJSONString(message),"HTTP-Response-"+message.getBizCode()+","+message.getMessageId());
			}
		}
		return message;
	}
}
